home *** CD-ROM | disk | FTP | other *** search
- ; [23-Feb-84]
- ; Added GETATTR routine and added attribute value to arglist of writer
- ; to support inverse video, blinking, etc.
- ; <BEEBE.IBM-PC>IBMSPEC.ASM.22, 20-Feb-84 13:52:00, Edit by BEEBE
- ; [20-Feb-84]
- ; alphabetized routines (except for SCREENHEIGHT and SCREENHEIGHT because
- ; of stupid assembler bug), prettyprinted code, inserted symbolic DOS/BIOS
- ; interrupts and function codes, added SCREENHEIGHT and CURRXY routines,
- ; made SCREENHEIGHT and SCREENWIDTH support standard IBM monitors as well
- ; as Quadram Quadscreen
- USE_SCROLL EQU 0
- TRY_INVERSE EQU 0
- DEBUG EQU 1
- assume cs:ibmspec
-
- public bell, currxy, eeol, eeos, getattr, gotoxy, screenheight, screenwidth
- public writer
-
- include ascii.inc
- include dos.inc
-
- ibmspec segment para public 'code'
-
- enter macro
- push bp ; save old frame pointer
- mov bp,sp ; make new frame pointer
- add bp,6 ; pointing to args on stack
- endm
-
- exit macro
- pop bp ; restore old frame pointer
- endm
-
- enterds macro
- push bp ; save old frame pointer and data
- push ds ; segment register
- mov bp,sp ; and make new frame pointer pointing to
- add bp,8 ; args on stack
- endm
-
- exitds macro
- pop ds ; restore data segment register and old
- pop bp ; frame pointer
- endm
-
- wonb equ 7 ; video mode for white char on black background
-
- ;=======================================================================
- ; Function Screenheight : word { return screen height in ax }
-
- assume cs:ibmspec
-
- screenheight proc far
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; current mode to al
- xor bx,bx ; clear bx
- mov ah,$QS_DESCRIBEMODE
- int $VIDEO ; get Quadscreen status (if any)
- test bx,bx ; bx = 0 still?
- jz stdht ; yes, standard IBM mode
- mov al,bh ; Quadscreen height
- xor ah,ah ; clear top half of ax
- ret
- stdht:
- mov ax,25 ; IBM modes 0..7 are all 25 lines
- ret
- screenheight endp
-
- ;=======================================================================
- ; Function Screenwidth : word { return screen width in ax }
-
- assume cs:ibmspec,ds:ibmspec
-
- screenwidth proc far
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; current mode to al
- xor bx,bx ; clear bx
- mov ah,$QS_DESCRIBEMODE
- int $VIDEO ; get Quadscreen status (if any)
- test bx,bx ; bx = 0 still?
- jz stdwd ; yes, standard IBM mode
- mov al,bl ; Quadscreen width
- xor ah,ah ; clear top half of ax
- ret ; return to caller
- stdwd:
- mov bl,al ; mode
- and bx,7 ; clear all but 3 lower bits
- sal bl,1 ; 2*mode for table word index
- push ds ; save ds
- push cs
- pop ds ; make ds = cs
- mov ax,wtable[bx] ; screen width according to mode
- pop ds ; restore ds
- ret ; return to caller
-
- wtable: dw 40 ; mode = 0
- dw 40 ; 1
- dw 80 ; 2
- dw 80 ; 3
- dw 80 ; 4
- dw 80 ; 5
- dw 80 ; 6
- dw 80 ; 7
-
- screenwidth endp
-
- ;=======================================================================
- ; Procedure Bell { ring the bell }
-
- assume cs:ibmspec
- kb_ctl equ 61h ; speaker I/O address
-
- bell proc far
- in al,kb_ctl
- push ax ; save current port contents
- mov bx,0c0h ; outer loop delay count
- b65:
- and al,0fch
- out kb_ctl,al
- mov cx,48h ; delay loop count
- b66:
- loop b66 ; do the delay
- or al,2
- out kb_ctl,al
- mov cx,48h ; delay loop count
- b67:
- loop b67 ; do the delay
- dec bx ; outer loop done?
- jnz b65 ; loop back if not
- pop ax ; recall original port contents
- out kb_ctl,al ; and restore them
- ret ; return to caller
- bell endp
-
- ;=======================================================================
- ; Procedure Currxy (column,row : word); { return current cursor position }
-
- assume cs:ibmspec
-
- currxy proc far
- enter
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; get current mode, width, page
- mov ah,$VIDEO_GETCURSORPOSITION
- int $VIDEO ; get (row,column) in (dh,dl)
- xor ah,ah ; clear top half of ax
- mov al,dl ; column
- mov [bp+2],ax ; store column
- mov al,dh ; row
- mov [bp],ax ; store row
- exit
- ret 4 ; return discarding stack arguments
- currxy endp
-
-
- ;=======================================================================
- ; Procedure Eeol { erase from cursor to end of line }
-
- assume cs:ibmspec
- db "<<EEOL>>"
- eeol proc far
- call screenwidth
- mov si,ax ; save screen width
- mov ah,$VIDEO_GETCURSORPOSITION
- int $VIDEO ; get cursor (row,column) in (dh,dl)
- xor dh,dh ; clear row
- sub si,dx ; length of remainder of screen line
- jle e1 ; exit if nothing to clear
- mov cx,si ; count
- mov al,' ' ; blank for clearing
- mov bl,wonb ; video attribute
- mov ah,$VIDEO_SETATTRCHAR
- int $VIDEO ; erase the rest of the line
- e1:
- ret ; return to caller
- eeol endp
-
- ;=======================================================================
- ; Procedure Eeos { erase from cursor to end of screen }
-
- assume cs:ibmspec
-
- db "<<EEOS>>"
- eeos proc far
- enter
- call screenwidth
- mov si,ax ; save screen width
- call screenheight
- mov di,ax ; save screen height
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; get current mode, width, and page (in bh)
- mov ah,$VIDEO_GETCURSORPOSITION
- int $VIDEO ; get (row,column) in (dh,dl)
- IF USE_SCROLL
- test dx,dx ; at (0,0)?
- jnz sloweeos ; no
- mov ax,di ; height
- dec al ; height-1
- mov dh,al ; height-1
- mov ax,si ; width
- dec al ; width-1
- mov dl,al ; (height-1,width-1) in (dh,dl) = lower right
- xor cx,cx ; set upper left corner of scroll = (0,0)
- xor al,al ; al = 0 means blank entire page
- mov ah,$VIDEO_SCROLLUP
- int $VIDEO ; do fast screen clear
- jmp eeosdone
- ENDIF
- sloweeos: ; slow erase of partial screen
- mov ax,di ; screen height
- mov cx,si ; screen width
- mul cl ; (height)*(width) = screen size in cx
- mov di,ax ; save screen size
- mov ax,si ; screen width
- mul dh ; (row)*(width) = count from bol to eos
- xor dh,dh ; column in dx
- sub di,ax ; (screen chars) - (count from bol to eos)
- sub di,dx ; - column =
- mov cx,di ; count of chars to blank
- mov al,' '
- mov bl,wonb ; video mode
- mov ah,$VIDEO_SETATTRCHAR
- int $VIDEO ; blank rest of screen
- eeosdone:
- exit
- ret
- eeos endp
-
- ;=======================================================================
- ; Function Getattr : word { Return video attr of character at cursor }
- ;
- assume cs:ibmspec
- db "<<GETATTR>>"
-
- getattr proc far
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; get current mode, width, and page
- mov ah,$VIDEO_GETATTRCHAR
- int $VIDEO
- mov al,ah ; attribute in al
- xor ah,ah ; clear top of ax (function result)
- ret ; return to caller
- getattr endp
-
-
- ;=======================================================================
- ; Procedure Gotoxy (column,row : word) { Move cursor to (column,row) }
-
- assume cs:ibmspec
- db "<<GOTOXY>>"
-
- gotoxy proc far
- enter
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; get current mode, width, and page
- mov dl,[bp+2] ; column
- mov dh,[bp] ; row
- xor bh,bh ; current page = 0
- mov ah,$VIDEO_SETCURSORPOSITION
- int $VIDEO
- exit
- ret 4 ; return discarding stack arguments
- gotoxy endp
-
- ;=======================================================================
- ; Procedure Writer (attr: word; thestr: adsmem; count: integer);
- ; { Write 'count' characters of 'thestr' at the current cursor position
- ; using video attribute attr (e.g. obtained by Getattr).
- ; Characters beyond the end-of-screen-line are not displayed. }
- ;
- ; Stack looks like
- ; 0 - count
- ; 2 - address of thestr
- ; 4 - segment of thestr
- ; 6 - attr
-
- assume cs:ibmspec
-
- ;
- ; IBM monitor attribute byte bit assignments
- ; -------------------------------------
- ; | blink | R | G | B | I | R | G | B |
- ; -------------------------------------
- ; ----- -----
- ; back fore
- ;
- blink equ 80h
- intensity equ 08h
- forergb equ 70h
- backrgb equ 07h
-
- db "<<WRITER>>"
- writer proc far
- enterds
- mov di,[bp] ; grab the count
- test di,di ; count > 0 ?
- jle writerdone ; exit if nothing to write
- mov si,[bp+2] ; grab the address of the characters to write
- mov ds,[bp+4] ; grab the segment of thestr
-
- call screenwidth
- push ax ; save screen width
- mov ah,$VIDEO_GETCURSORPOSITION
- int $VIDEO
- pop ax ; recall screen width
- dec ax ; al = width of screen, dl = cursor column
- mov bl,al ; save maximum displayable column in bl
- sub al,dl ; maximum number of chars to write
- jle writerdone ; exit if nothing to write
- xor ah,ah ; clear top of ax
- cmp di,ax ; user-specified count > remaining line length?
- jle writ2 ; no
- mov di,ax ; yes, truncate the line
- writ2:
- cld ; clear direction flag to increment si
- mov ah,$VIDEO_GETVIDEOSTATE
- int $VIDEO ; get current page in (bh)
- mov ah,$VIDEO_GETCURSORPOSITION
- int $VIDEO ; get (row,column) in (dh,dl)
- push dx ; save it - later accessed by [bp-10]
-
- writlp:
- lodsb ; get next byte into al and increment si
- mov cx,1 ; repeat count = 1
- cmp al,.HT ; tab?
- jne writ3 ; no
- mov cl,[bp-10] ; yes, get current cursor column (0,1,2,...)
- and cl,7 ; cl MOD 8
- neg cl ; -(cl MOD 8)
- add cl,8 ; 8 - (cl MOD 8) = columns of blank fill
- mov al,' ' ; change tab to blank
-
- writ3:
- mov dl,[bp-10] ; current column
- add dl,cl ; new column
- cmp bl,dl ; maximum column < new current column?
- jl writerdone ; yes, no more room in current line
- mov [bp-10],dl ; update cursor column
- if DEBUG
- mov bl,7
- else
- mov bl,[bp+6] ; get attribute byte
- endif
- if TRY_INVERSE
- ;
- ; display the character in the inverse of the current mode
- ; [experiment]
- ;
-
- mov ah,$VIDEO_GETATTRCHAR
- int $VIDEO ; get (attribute,char) in (ah,al) for page (bh)
- push cx ; save count
- mov bl,ah ; mode byte
- and bl,blink+intensity ; keep blink and intensity bits
- and ah,NOT (blink OR intensity) ; remove blink and intensity
- mov ch,ah
- mov cl,4 ; shift count
- shr ch,cl ; move foreground into background,
- shl ah,cl ; background into foreground,
- or ah,ch ; merge them,
- or ah,bl ; restore blink and intensity for new mode,
- pop cx ; restore count
- mov bl,ah ; and setup new mode.
- endif
-
- writ4:
- mov ah,$VIDEO_SETATTRCHAR
- int $VIDEO ; write char and attribute
- mov dl,[bp-10] ; get current cursor column
- mov ah,$VIDEO_SETCURSORPOSITION
- int $VIDEO ; move cursor
- dec di ; are we done?
- jnz writlp ; loop for more if not
- pop dx ; restore saved dx
-
- writerdone:
- exitds ; restore stack at entry
- ret 8 ; return discarding arguments on stack
- writer endp
-
- ibmspec ends
- end